package org.stragma.symbian;

import org.stragma.symbian.apply.RewritingTypes;
import org.stragma.symbian.units.AddAssertionsUnit;
import org.stragma.symbian.units.ApplyParenUnit;
import org.stragma.symbian.units.BeautifyUnit;
import org.stragma.symbian.units.DesugarUnit;
import org.stragma.symbian.units.DoApplyUnit;
import org.stragma.symbian.units.EnsugarCUnit;
import org.stragma.symbian.units.NormaliseUnit;
import org.stragma.symbian.units.SimplifyUnit;
import org.stragma.symbian.units.ImageMatrixUnit;
import org.stragma.symbian.units.UnitFactory;

/**
 * @author shirren
 * This class implements the statistics command which provides results on a particular tree
 */
public class PerformanceTestCommand implements ICommand {

	private String[] args;
	
	/**
	 * @param args2
	 * Custom constructor which accepts a list of arguments
	 */
	public PerformanceTestCommand(String[] args) {
		if (args.length != 4) {
			throw new IllegalArgumentException("The statistics command only takes three arguments.");
		}
		this.args = args;
	}
	
	/* (non-Javadoc)
	 * @see org.stragma.symbian.ICommand#execute(java.util.Iterator)
	 */
	@Override
	public void execute() {
		ITestable unit = getTestType();

		if (isKiamaTest()) {
			unit.testKiama(getSourceDataLocation());	
		} else {
			unit.testStratego(getSourceDataLocation());
		}
	}
	
	/**
	 * Converts a string argument to a Java type
	 */
	private ITestable getTestType() {
		RewritingTypes rewritingTypes = RewritingTypes.valueOf(args[2]);
		
		switch (rewritingTypes) {
			case desugar:
				UnitFactory<DesugarUnit> desFactory = new UnitFactory<DesugarUnit>();
				return desFactory.createUnit(DesugarUnit.class);
			case applyParen:
				UnitFactory<ApplyParenUnit> factory = new UnitFactory<ApplyParenUnit>();
				return factory.createUnit(ApplyParenUnit.class);
			case ensugarC:
				UnitFactory<EnsugarCUnit> ensugarCFactory = new UnitFactory<EnsugarCUnit>();
				return ensugarCFactory.createUnit(EnsugarCUnit.class);
			case normalise:
				UnitFactory<NormaliseUnit> normaliseUnitFactory = new UnitFactory<NormaliseUnit>();
				return normaliseUnitFactory.createUnit(NormaliseUnit.class);
			case addAssertions:
				UnitFactory<AddAssertionsUnit> addAssertionsUnitFactory = new UnitFactory<AddAssertionsUnit>();
				return addAssertionsUnitFactory.createUnit(AddAssertionsUnit.class);
			case beautify:
				UnitFactory<BeautifyUnit> beautifyUnitFactory = new UnitFactory<BeautifyUnit>();
				return beautifyUnitFactory.createUnit(BeautifyUnit.class);
			case doApply:
				UnitFactory<DoApplyUnit> doApplyUnitFactory = new UnitFactory<DoApplyUnit>();
				return doApplyUnitFactory.createUnit(DoApplyUnit.class);
			case simplify:
				UnitFactory<SimplifyUnit> simplifyUnitFactory = new UnitFactory<SimplifyUnit>();
				return simplifyUnitFactory.createUnit(SimplifyUnit.class);
			case imageMatrix:
				UnitFactory<ImageMatrixUnit> imgMatrixUnitFactory = new UnitFactory<ImageMatrixUnit>();
				return imgMatrixUnitFactory.createUnit(ImageMatrixUnit.class);
			default:
				// We are using system println because we do not want the performance of our app to be adversely affected
				System.out.println("Unsupported test type " + args[2]);
				return null;
		}
	}

	/**
	 * Tells us if it is a Kiama test or not
	 */
	private boolean isKiamaTest() {
		if (args[1].toLowerCase().equals("kiama")) {
			return true;
		}
		return false;
	}
	
	/**
	 * Returns the location of the test data
	 */
	private String getSourceDataLocation() {
		// We are using system println because we do not want the performance of our app to be adversely affected
		return args[3];
	}
}
